package com.mjk.common.web.getway.conf.selector;


import cn.hutool.core.util.ArrayUtil;
import com.mjk.common.base.error.BizException;
import com.mjk.common.util.ObjectUtils;
import com.mjk.common.web.getway.annotation.EnableGetWay;
import com.mjk.common.web.getway.restful.prototal.ws.conf.WsImportConfig;
import com.mjk.common.web.getway.transfer.GetwayTransferType;
import com.mjk.common.web.getway.transfer.http.HttpGetWayprotocol;
import com.mjk.common.web.getway.utils.loadbalancer.LoadBalanceType;
import com.mjk.common.web.getway.utils.loadbalancer.impl.*;
import org.apache.dubbo.config.spring.context.annotation.DubboConfigConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.cloud.client.discovery.EnableDiscoveryClientImportSelector;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

import java.util.ArrayList;
import java.util.List;

/**
 * 通过开关 判断开启那种模式的协议
 * http
 * cloud
 * dubbo
 * @author mjk
 *
 */
public class BeeGetWaySelector implements BeanFactoryAware ,DeferredImportSelector {
	private BeanFactory factory;
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
                EnableGetWay.class.getName(), false));
		if(null == attributes){
			return new String[]{};
		}
		GetwayTransferType transferType = (GetwayTransferType)attributes.get("transferType");
		String prototcol = transferType.getPrototalName();

		System.setProperty("management.health.mongo.enabled", Boolean.toString(false));
		System.setProperty("management.health.rabbit.enabled", Boolean.toString(false));
		System.setProperty("management.health.elasticsearch.enabled", Boolean.toString(false));
		System.setProperty("management.health.db.enabled", Boolean.toString(false));
		System.setProperty("management.health.diskspace.enabled", Boolean.toString(false));
		System.setProperty("management.health.redis.enabled", Boolean.toString(false));
		if(ObjectUtils.isEmpty(prototcol)){
			throw new BizException("transferType is not supper null");
		}
		List<String> loadClazz = new ArrayList<>();
		switch (transferType){
			case DUBBO->{
				System.setProperty("eureka.client.enabled", Boolean.toString(false));
				loadClazz.add(DubboConfigConfiguration.Single.class.getName());
				loadClazz.add(BeeDubboComponentScanRegistrar.class.getName());
				loadClazz.add(BeeDubboTransferRegistrar.class.getName());
				break;
			}
			case CLOUD -> {
				loadClazz.add(BeeCloudTransferRegistrar.class.getName());
				loadClazz.add(EnableDiscoveryClientImportSelector.class.getName());
				break;
			}
			case HTTP -> {
				System.setProperty("eureka.client.enabled", Boolean.toString(false));
				if(!factory.containsBean(HttpGetWayprotocol.class.getName())){
					loadClazz.add(HttpGetWayprotocol.class.getName());
					loadClazz.add(WsImportConfig.class.getName());
				}
			}
		}
		//初始化负载均衡策略
		LoadBalanceType loadBalanceType = (LoadBalanceType)attributes.get("balanceType");
		switch (loadBalanceType){
			case ROUND -> {
				loadClazz.add(RoundRobinLoadBalance.class.getName());
				break;
			}
			case LEAST -> {
				loadClazz.add(LeastConnectionsLoadBalance.class.getName());
				break;
			}
			case RANDOM -> {
				loadClazz.add(RandomLoadBalance.class.getName());
				break;
			}
			case CONSISTENDHASH -> {
				loadClazz.add(ConsistentHashLoadBalance.class.getName());
				break;
			}
			case WEIGHTEDRANDOM -> {
				loadClazz.add(WeightedRandomLoadBalance.class.getName());
				break;
			}
			case WEIGHTEDROUND -> {
				loadClazz.add(WeightedRoundRobinLoadBalance.class.getName());
				break;
			}
		}
		return ArrayUtil.toArray(loadClazz,String.class);
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.factory = beanFactory;
	}
}
